#pragma once
#include <string>

namespace krryn{
namespace core_imp{
	class blockable;
	class thread_handle;
	class event_handle;
	class mutex_handle;
	class wait_all_handle;
}

namespace core{
	class event{
	public:
		event(const std::string &a_Name);
		~event();

		std::string name();
		void trigger() volatile;
		bool wait() volatile;
	private:
		core_imp::event_handle *m_Handle;
		std::string m_Name;
	};

	/// RAII helper class for locks
	template<typename T>
	class locker{
	public:
		locker(T& a_Lock) : m_Lock(a_Lock){ m_Lock.lock(); }
		~locker() { m_Lock.unlock(); }
	private:
		T& m_Lock;
	};

	class mutex{
	public:
		mutex();
		~mutex();

		void lock();
		void unlock();
	private:
		core_imp::mutex_handle *m_Handle;
	};

	class thread{
	public:
		thread();
		~thread();

		virtual void run() = 0;

		void kill();
		void start();
		void end();
		static void sleep(long a_MilliSecond);
	private:
		// Classes shouldn't have friends! :'(
		friend class wait_all;

		core_imp::thread_handle *m_Handle;
	};

	class wait_all{
	public:
		wait_all(thread **a_Threads, int a_Amount);
	};
}
}
